package com.gxa.weixing.pc.controller;

import com.github.pagehelper.PageInfo;
import com.gxa.weixing.core.common.ExceptionCode;
import com.gxa.weixing.core.common.JsonResult;
import com.gxa.weixing.core.exception.BusinessException;
import com.gxa.weixing.core.pojo.Manager;
import com.gxa.weixing.core.pojo.Menu;
import com.gxa.weixing.core.pojo.Role;
import com.gxa.weixing.core.pojo.Shop;
import com.gxa.weixing.core.util.ShiroMd5;
import com.gxa.weixing.core.util.StringUtil;
import com.gxa.weixing.pc.service.ManagerService;
import com.gxa.weixing.pc.service.RoleService;
import com.gxa.weixing.pc.service.ShopService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import java.text.ParseException;
import java.util.List;
import java.util.Map;
import java.util.UUID;

/**
 * @Author ws
 * @date 2022/01/05 16:51
 **/
@RestController
@Api(tags = "管理员相关的api")
@RequestMapping("/manager")
public class ManagerController {

    @Autowired
    ManagerService managerService;

    @Autowired
    ShopService shopService;

    @Autowired
    RoleService roleService;

    @ApiOperation(value = "管理员登录接口")
    @PostMapping("/login")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "phone",value = "手机号",dataType = "String",paramType = "query"),
            @ApiImplicitParam(name = "password",value = "密码",dataType = "String",paramType = "query"),
    })
    public Map login(@RequestParam("phone") String phone, @RequestParam("password") String pwd) throws Exception {



        // Subject shiro权限认证主体对象
        // TODO getSubject() 获取的对象是否唯一 (参考: getSession,有则不创建，无则创建)
        Subject subject = SecurityUtils.getSubject();
        // 判断用户是否验证,防止多次登录
        if (!subject.isAuthenticated()) {
            // shiro权限认证主体对象 把前端传递的用户名和密码封装到 UsernamePasswordToken 中
            // 注意: 此处的pwd值封装到token之后，realm要进行加密处理，以便于和数据库中加密密码匹配
            String s = ShiroMd5.shiroMd5( pwd);
            UsernamePasswordToken upToken = new UsernamePasswordToken(phone, s);
            try {
                // 调用realm认证用户权限
                subject.login(upToken);

                // 生成uuid做token,存入数据库
                String token = UUID.randomUUID().toString().replace("-", "");


                // 返回前端权限菜单列表
                Manager manager = managerService.getByPhone(phone);
                List<Menu> menus = managerService.getMenus(phone);

                // 验证成功，给前端返回信息
                JsonResult jsonResult = new JsonResult();
                jsonResult.setMsg("登录成功");
                jsonResult.put("managerId",manager.getManagerId());
                jsonResult.put("managerName",manager.getManagerName());
                jsonResult.put("headPhoto",manager.getManagerHeadPhoto());
                jsonResult.put("menuList",menus);
                jsonResult.setCode("200");

                return jsonResult.getDataMap();

            } catch (IncorrectCredentialsException ice) {
                // return "用户名/密码不匹配！";
                throw new BusinessException(ExceptionCode.LOGIN_FAILED);
            } catch (LockedAccountException lae) {
                // return "账户已被冻结！";
                throw new BusinessException(ExceptionCode.ACCOUNT_FAILED);
            } catch (UnknownAccountException uae) {
                // return "账户不存在！";
                throw new BusinessException(ExceptionCode.ACCOUNT_NOTFIND);
            } catch (AuthenticationException ae) {
                // return ae.getMessage();
                throw new Exception(ae.getMessage());
            }
        }
        return null;
    }

    @ApiOperation(value = "管理员登出接口")
    @PostMapping("/logout")
    public Map logout() {
        JsonResult jsonResult = new JsonResult();
        jsonResult.setCode("200");
        jsonResult.setMsg("退出成功");
        return jsonResult.getDataMap();
    }

    /**
     * 添加管理员的接口，由于涉及到其他表，所以使用map接收
     * @param map shopId: 所属门店的编号
     *            name: 管理员姓名
     *            phone: 管理员手机号
     *            roleId: 权限配置/对应权限组的编号
     *            state: 管理员账号的状态(0/冻结 1/正常)
     *
     * @return
     */
    @ApiOperation(value = "新增管理员接口")
    @PostMapping("/add")
    @ApiImplicitParam(name = "map",value = "json字符串",dataType = "Map",paramType = "body")
    public Map add(@RequestBody Map<String,String> map) throws BusinessException {
        // 对参数进行校验
        if (StringUtils.isEmpty(map.get("shopId")) ||
            StringUtils.isEmpty(map.get("name")) ||
            StringUtils.isEmpty(map.get("phone")) ||
            StringUtils.isEmpty(map.get("roleId")) ||
            StringUtils.isEmpty(map.get("state")) ) {
            throw new BusinessException(ExceptionCode.PARAM_NOTNULL);
        }
        if (!StringUtil.isPhoneNumber(map.get("phone"))) {
            throw new BusinessException(ExceptionCode.WRONG_PHONE);
        }

        Integer add = managerService.add(map);
        JsonResult jsonResult = new JsonResult();
        if (add == 1) {
            jsonResult.setCode("200");
            jsonResult.setMsg("添加成功");
        }else {
            jsonResult.setCode("300");
            jsonResult.setMsg("添加失败");
        }
        return jsonResult.getDataMap();
    }

    /**
     * 修改管理员的接口，由于涉及到其他表，所以使用map接收
     * @param map id: 管理员的编号
     * 、         shopId: 所属门店的编号
     *            name: 管理员姓名
     *            phone: 管理员手机号
     *            roleId: 权限配置/对应权限组的编号
     *            state: 管理员账号的状态(0/冻结 1/正常)
     *
     * @return
     */
    @ApiOperation(value = "修改管理员信息接口")
    @PostMapping("/update")
    @ApiImplicitParam(name = "map",value = "json字符串",dataType = "Map",paramType = "body")
    public Map update(@RequestBody Map<String,String> map) throws BusinessException {
        Integer update = managerService.update(map);

        JsonResult jsonResult = new JsonResult();
        if (update == 1) {
            jsonResult.setCode("200");
            jsonResult.setMsg("更新成功");
        }else {
            jsonResult.setCode("300");
            jsonResult.setMsg("更新失败");
        }
        return jsonResult.getDataMap();
    }

    @ApiOperation(value = "删除管理员接口")
    @PostMapping("/delete")
    @ApiImplicitParam(name = "id",value = "管理员编号",dataType = "long",paramType = "query")
    public Map delete(@RequestParam("id") Long id) throws BusinessException {
        // 校验参数
        if(StringUtils.isEmpty(id)){
            throw new BusinessException(ExceptionCode.PARAM_NOTNULL);
        }

        Integer integer = managerService.delete(id);
        JsonResult jsonResult = new JsonResult();
        if (integer == 1) {
            jsonResult.setCode("200");
            jsonResult.setMsg("删除成功");
        }else {
            jsonResult.setCode("300");
            jsonResult.setMsg("删除失败");
        }
        return jsonResult.getDataMap();
    }

    @ApiOperation(value = "分页全查询")
    @GetMapping("/getAll")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "page",value = "页数"),
            @ApiImplicitParam(name = "size",value = "每页记录数"),
    })
    public Map getAll(@RequestParam("page") Integer page, @RequestParam("size") Integer size) throws ParseException, BusinessException {
        // 参数校验
        if (StringUtils.isEmpty(page) || page <0){
            throw new BusinessException(ExceptionCode.PAGE_OR_SIZE_ERROR);
        }
        if (StringUtils.isEmpty(size) || size <0){
            throw new BusinessException(ExceptionCode.PAGE_OR_SIZE_ERROR);
        }

        PageInfo info = managerService.getAll(page, size);
        long total = info.getTotal();
        List list = info.getList();

        JsonResult jsonResult = new JsonResult();
        jsonResult.setCode("200");
        jsonResult.setData(list);
        jsonResult.put("total",total);
        return jsonResult.getDataMap();
    }

    @ApiOperation(value = "分页带条件查询查询")
    @GetMapping("/geListBy")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "page",value = "页数"),
            @ApiImplicitParam(name = "size",value = "每页记录数"),
            @ApiImplicitParam(name = "shopId",value = "门店编号"),
            @ApiImplicitParam(name = "name",value = "管理员姓名"),
            @ApiImplicitParam(name = "state",value = "管理员状态"),
    })
    public Map getListBy(Long shopId, String name, Long state,
                         @RequestParam("page") Integer page, @RequestParam("size") Integer size) throws ParseException, BusinessException {
        // 参数校验
        if (StringUtils.isEmpty(page) || page <0){
            throw new BusinessException(ExceptionCode.PAGE_OR_SIZE_ERROR);
        }
        if (StringUtils.isEmpty(size) || size <0){
            throw new BusinessException(ExceptionCode.PAGE_OR_SIZE_ERROR);
        }

        PageInfo info = managerService.getListBy(page, size, shopId, state, name);
        long total = info.getTotal();
        List list = info.getList();

        JsonResult jsonResult = new JsonResult();
        jsonResult.setCode("200");
        jsonResult.setData(list);
        jsonResult.put("total",total);
        return jsonResult.getDataMap();
    }

    @ApiOperation(value = "获取所有门店信息")
    @GetMapping("/getShop")
    public Map getShopList(){
        List<Shop> shops = shopService.selectAll();

        JsonResult jsonResult = new JsonResult();
        jsonResult.setCode("200");
        jsonResult.setData(shops);
        return jsonResult.getDataMap();
    }

    @ApiOperation(value = "获取所有所有角色对象")
    @GetMapping("/getRole")
    public Map getRoleList(){
        List<Map> roles = roleService.getRoleListWithPermissions();

        JsonResult jsonResult = new JsonResult();
        jsonResult.setCode("200");
        jsonResult.setData(roles);
        return jsonResult.getDataMap();
    }


}
